﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace ArgusPCLib.Mathematics
{
	/// <summary>
	/// Implementors must declare the following Properties:
	/// <code>
	/// public static T Zero { get; }
	/// public static T One { get; }
	/// </code>
	/// where T is the implementing type (T : IScalar).
	/// 
	/// T.Zero should return the neutral element of addition,
	/// so that scalar.IsEqualtTo(scalar.Add(T.Zero)) returns
	/// true for any value scalar of type T.
	/// 
	/// T.One should return the neutral element of multiplication,
	/// so that scalar.IsEqualtTo(scalar.Multiply(T.One)) returns
	/// true for any value scalar of type T.
	/// </summary>
	/// <seealso cref="ArgusPCLib.Mathematics.Reflection.ScalarReflector"/>
	/// <seealso cref="ArgusPCLib.Mathematics.Reflection.ScalarReflector{T}"/>
	/// <seealso cref="ArgusPCLib.Mathematics.Reflection.ScalarReflector.PropertyNames"/>
	public interface IScalar : IOperand
	{
		IScalar Add(IScalar value);
		IScalar Multiply(IScalar value);
		IScalar Subtract(IScalar value);
		IScalar Divide(IScalar value);
		bool IsEqualTo(IScalar value);
	}

	public interface ILinearScalar : IScalar, IComparable
	{
		bool IsGreaterThan(ILinearScalar value);
		bool IsSmallerThan(ILinearScalar value);
	}

#if false
		#region IScalar
		string IFormattable.ToString(string format, IFormatProvider formatProvider)
		{
			throw new NotImplementedException();
		}

		bool IScalar.IsEqualTo(IScalar scalar)
		{
			return (this == (ScalarType)scalar);
		}

		IScalar IScalar.Divide(IScalar scalar)
		{
			return (this / (ScalarType)scalar);
		}

		IScalar IScalar.Subtract(IScalar scalar)
		{
			return (this - (ScalarType)scalar);
		}

		IScalar IScalar.Multiply(IScalar scalar)
		{
			return (this * (ScalarType)scalar);
		}

		IScalar IScalar.Add(IScalar scalar)
		{
			return (this + (ScalarType)scalar);
		}

		IScalar IScalar.GetCopy()
		{
			return new ScalarType(this);
		}
		#endregion

		#region ILinearScalar
		bool ILinearScalar.IsSmallerThan(ILinearScalar scalar)
		{
			return (this < (ScalarType)scalar);
		}

		bool ILinearScalar.IsGreaterThan(ILinearScalar scalar)
		{
			return (this > (ScalarType)scalar);
		}
		#endregion
#endif
}
